home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!snorkelwacker!apple!netcom!amdcad!sun!mipsdal.mips.com
- From: riley@mipsdal.mips.com (Riley Rainey)
- Newsgroups: comp.sources.x
- Subject: v09i072: acm, X aerial combat simulation, Part04/05
- Message-ID: <143451@sun.Eng.Sun.COM>
- Date: 7 Oct 90 18:13:23 GMT
- References: <csx-09i069:acm@uunet.UU.NET>
- Sender: news@sun.Eng.Sun.COM
- Lines: 2041
- Approved: argv@sun.com
-
- Submitted-by: riley@mipsdal.mips.com (Riley Rainey)
- Posting-number: Volume 9, Issue 72
- Archive-name: acm/part04
-
- echo x - ./fsim/acm.1
- sed 's/^X//' >./fsim/acm.1 <<'*-*-END-of-./fsim/acm.1-*-*'
- X.TH ACM l "4 September 1990"
- X.SH NAME
- Xacm \- an aerial combat simulator for X
- X.SH SYNOPSIS
- X.B acm [ server ] [ options \]
- X.LP
- X
- X.SH DESCRIPTION
- X
- Xacm is an air combat simulator that runs under the X window system. Up to
- Xeight players can engage in simultaneous air combat. Players fly jet aircraft
- Xequipped with radar, heat seeking missiles and cannon.
- X
- XThe program, "acm", calls a deamon already running on the specified
- Xserver_hostname and requests that your enter the game. The shell variable
- X"ACMSERVER" optionally specifies the name of the server host.
- X
- XEach player flies something close to either an F-16C Falcon or MIG-23.
- X
- X
- X.SH USAGE REFERENCE
- X
- XTo begin play, the flight simulator server must be started manually on a
- Xsystem that is accessible to all players.
- X
- XThe following command line will do that:
- X
- X.LP
- X.TP
- X % acms
- X
- XThe following command line options are recognized by acm:
- X.LP
- X.TP
- X-geometry geometry_spec
- XAn X compatible window geometry specification
- X.TP
- X-team <1 or 2>
- XSpecifies the starting airfield. Airfields are about 50 nm apart.
- XTeam 1 flies F-16's, team 2 flies MIG-23's.
- X
- X
- X.SH HOW TO TAKE-OFF
- X
- X
- XYour mouse is the control stick. The neutral position is the center of your
- Xview display -- denoted by the dot in the center of your heads-up-display (HUD).
- XMoving the mouse away from you pitches the plane down, moving it back
- Xpitches the plane up. Left and right inputs roll the aircraft in the
- Xcorresponding direction. On the ground at speeds up to 100 kts, nose
- Xwheel steering guides the aircraft.
- X
- XTo take off for the first time, select 20 degrees of flaps (press H twice),
- Xthen press the full throttle key (the 4 key on the main keyboard). Keep the
- Xmouse in the neutral position until you are moving at about 140 kts, then pull
- Xthe mouse about two-thirds of the way down the view window. You should pitch
- Xup and lift off the ground fairly easily. Gradually move the stick closer
- Xto the neutral position and let your airspeed build -- don't move it back to
- Xneutral too quickly or you will end up back on the ground again! As your
- Xairspeed passes about 250 kts, raise the flaps (press Y twice). Congratulations,
- Xyou're flying a multi-million dollar jet.
- X
- X
- X.SH ENGINE CONTROLS
- X
- X
- XThe following keys control your engine thrust:
- X
- X.LP
- X 4 Full Power
- X.LP
- X 3 Increase Power (about 2 percent)
- X.LP
- X 2 Decrease Power (about the same amount)
- X.LP
- X 1 Idle Power
- X.LP
- X A Toggle Afterburner
- X
- XYour engine gauge displays the power that you are generating. Below that,
- Xyou have displays showing your total fuel remaining as well as your current
- Xfuel consumption rate. The afterburner uses fuel at an amazing rate; use it
- Xwisely.
- X
- X
- X.SH LOOKING AROUND
- X
- X
- XThe keys of the numeric keypad control which direction you're looking outside
- Xof the cockpit:
- X
- X.LP
- X 8 Forward
- X.LP
- X 4 Left 5 Up 6 Right
- X.LP
- X 2 Aft
- X
- XIt pays to look around when you're in a combat environment. Your chances
- Xof staying alive increase remarkably.
- X
- X
- X.SH THE HEADS UP DISPLAY (HUD)
- X
- X
- XOn the left side of the HUD is a ladder showing your current airspeed in
- Xnautical miles per hour (it displays true airspeed). Above that, in the
- Xupper left corner, is a G-meter.
- X
- XThe right ladder shows altitude; above that
- Xis a readout of your current angle-of-attack in degrees ("a=X.X").
- XYour
- Xjet will stall at a 30 degrees positive angle of attack and negative 16
- Xdegrees.
- X
- XThe airplane symbol (something like "-O-") shows the direction
- Xthat the relative wind is coming from. The relative wind combines your
- Xcurrent angles of attack and sideslip. A ladder in the center of the
- XHUD show your aircraft's current attitude.
- X
- XThe lower, horizontal ladder shows your current heading. Discretes in the
- Xlower left-hand corner show the state of your weapons systems. Slightly
- Xabove them is a readout of your current thrust percentage as well as the
- Xstate of your engine's afterburner -- the "AB" symbol means the
- Xafterburner is on.
- X
- X
- X.SH USING YOUR RADAR DISPLAY
- X
- X
- XThe radar system has a field of view of 130 degrees vertically and side-to-side.
- XRadar automatically locks onto the closest threat in its field of view. A
- Xlocked target is displayed as a solid block. Other hostile targets are
- Xdisplayed as hollow squares.
- X
- XTargetting information is displayed in the lower right corner of the display.
- XThe top number is the heading of the locked target, the next number is the
- Xrelative heading you should steer to intercept the target (displayed as
- X"ddd R", and the third number is the rate that you are closing with this
- Xtarget, expressed in knots.
- X
- XYou can lock onto other targets by pressing the target designator key (Q).
- X
- X
- X.SH WHO'S GUNNING FOR ME?
- X
- X
- XRadar sets that are tracking your aircraft can be detected. Your Threat
- XEarly Warning System (TEWS) display warns you of potential threats. This
- Xcircular display shows the relative direction of radars (other aircraft)
- Xthat are looking at you.
- X
- X.SH ARMAMENTS
- X
- X
- XYour aircraft is equipped with heat-seeking missiles and a 20 millimeter
- Xcannon. Weapon information is displayed in the lower left-hand corner of
- Xyour HUD. Different weapons may be selected by pressing mouse button 3.
- X
- XThe missiles are patterned after U.S. AIM-9M Sidewinders. They can
- Xdetect infared (IR) targets at any aspect (not just from the rear). Their
- Xrange varies dramatically with the altitude and closure rate. The
- Xmissile subsystem couples with your radar set to provide time-to-impact
- Xinformation when AIM-9's are selected.
- X
- X
- X.SH EXAMPLES
- X
- X acm bismarck
- X
- X acm bismarck -geometry 1000x500
- X
- X.SH KEYBOARD COMMAND LIST
- X
- X
- X
- XEngine Controls
- X
- X.LP
- X4 -- Full Power
- X.LP
- X3 -- Increase Power
- X.LP
- X2 -- Decrease Power
- X.LP
- X1 -- Idle
- X.LP
- XA -- Toggle Afterburner State
- X
- X
- X
- XRadar Controls
- X
- X.LP
- XR -- Toggle Radar State (On/Standby)
- X.LP
- XQ -- Target Designator
- X
- X
- X
- XFlaps
- X
- X.LP
- XH -- Extend 10 degrees
- X.LP
- XY -- Retract 10 degrees
- X
- X
- X
- XSpeed Brakes
- X
- X.LP
- XS -- Extend
- X.LP
- XW -- Retract
- X
- X
- X
- XOther Controls
- X
- X.LP
- XP -- Self-Destruct (Quit the game)
- X.LP
- XL -- Launch a target drone
- X
- X
- X
- XView Controls (Numeric Keypad)
- X
- X.LP
- X8 -- Forward
- X.LP
- X2 -- Aft
- X.LP
- X4 -- Left
- X.LP
- X6 -- Right
- X.LP
- X5 -- Up
- X
- X
- X.SH NOTES FOR THE ADVANCED USER
- X
- XIf you turn your radar set to standby (the R key toggles your radar sets
- XON/STANDBY state), you don't emit radar signals, and, hence "disappear" from
- Xeveryone elses TEWS display. It's harder to acquire targets visually, but it
- Xmay allow you to close in for the kill without alerting an opponent.
- X
- X
- X
- X.SH AUTHOR
- XRiley Rainey, riley@mips.com
- *-*-END-of-./fsim/acm.1-*-*
- echo x - ./fsim/manifest.h
- sed 's/^X//' >./fsim/manifest.h <<'*-*-END-of-./fsim/manifest.h-*-*'
- X/*
- X * UPDATE_INTERVAL define the number of microseconds between
- X * each position update when the game is running.
- X */
- X
- X#define UPDATE_INTERVAL 125000
- X
- X/*
- X * REDRAW_EVERY defines the number of update intervals between each
- X * redraw of player screens.
- X */
- X
- X#define REDRAW_EVERY 4
- X
- X/*
- X * ACM_PORT define the internet port number to be used in the game
- X * startup handshaking.
- X */
- X
- X#define ACM_PORT 3232
- X
- X/*
- X * ACM becomes the name used to lookup X resources on a particular
- X * X server.
- X */
- X
- X#define ACM "acm"
- X
- X/*
- X * Linear response to control stick inputs can make the plane harder
- X * to fly.
- X */
- X
- X/* #define LINEAR_CONTROL_RESPONSE */
- *-*-END-of-./fsim/manifest.h-*-*
- echo x - ./fsim/newPlayer.c
- sed 's/^X//' >./fsim/newPlayer.c <<'*-*-END-of-./fsim/newPlayer.c-*-*'
- X/*
- X * xflight : an aerial combat simulator for X
- X *
- X * Written by Riley Rainey, riley@mips.com
- X *
- X * Permission to use, copy, modify and distribute (without charge) this
- X * software, documentation, images, etc. is granted, provided that this
- X * comment and the author's name is retained.
- X *
- X */
- X
- X#include "pm.h"
- X#include <stdio.h>
- X#include <X11/Xutil.h>
- X
- X#define BORDER 1
- X#define FONT "*courier-bold-r-normal--17*"
- X#define ARG_FONT "font"
- X#define ARG_RADAR_FONT "radarFont"
- X#define ARG_BORDER_COLOR "borderColor"
- X#define ARG_BORDER "borderWidth"
- X#define ARG_GEOMETRY "geometry"
- X#define DEFAULT_BACKGROUND "#93bde4" /* my version of sky blue */
- X#define DEFAULT_BORDER "black"
- X#define DEFAULT_RADAR_FONT "fixed"
- X
- X#define SW_BORDER 1
- X#define SW_BACKGROUND 2
- X#define SW_HUDFONT 3
- X#define SW_GEOM 4
- X#define SW_RADARFONT 5
- X#define SW_TEAM 6
- X
- Xstruct {
- X char *sw;
- X int value;
- X } swt[] = {
- X "-bw", SW_BORDER,
- X "-skycolor", SW_BACKGROUND,
- X "-hudfont", SW_HUDFONT,
- X "-radarfont",SW_RADARFONT,
- X "-geometry", SW_GEOM,
- X "-team", SW_TEAM,
- X NULL, 0}, *swp;
- X
- XXWMHints xwmh = {
- X (InputHint|StateHint), /* flags */
- X False, /* input */
- X NormalState, /* initial_state */
- X 0, /* icon pixmap */
- X 0, /* icon window */
- X 0, 0, /* icon location */
- X 0, /* icon mask */
- X 0, /* Window group */
- X};
- X
- Xvoid recoverAcmArgv (args, argc, argv)
- Xchar *args;
- Xint *argc;
- Xchar *argv[]; {
- X
- X char *s;
- X
- X argv[0] = ACM;
- X argv[1] = args;
- X
- X if (*args == '\0') {
- X *argc = 1;
- X argv[1] = (char *) NULL;
- X return;
- X }
- X else
- X *argc = 2;
- X
- X for (s=args; *s;) {
- X if (*s == '|') {
- X *s = '\0';
- X argv[(*argc)++] = ++s;
- X }
- X else
- X ++s;
- X }
- X
- X argv[*argc] = (char *) NULL;
- X}
- X
- Xint newPlayer(s, display, logname, switches)
- Xint s;
- Xchar *display;
- Xchar *logname;
- Xchar *switches; {
- X
- X char *fontName; /* Name of font for string */
- X XSizeHints xsh; /* Size hints for window manager */
- X Colormap cmap;
- X GC curGC;
- X XGCValues gcv;
- X unsigned long pad; /* Font size parameters */
- X unsigned long bd; /* Pixel values */
- X unsigned long bw; /* Border width */
- X char *tempstr; /* Temporary string */
- X XColor color; /* Temporary color */
- X char *geomSpec; /* Window geometry string */
- X XSetWindowAttributes xswa; /* Temporary Set Window Attribute struct */
- X char **c;
- X char err[64];
- X static char *background = NULL;
- X int borderWidth = 1;
- X int i, player;
- X int width, height;
- X viewer *u;
- X craft *cf;
- X double scale;
- X int argc;
- X char *argv[32];
- X int screen, mono;
- X char *hudfont = NULL, *radarfont = NULL;
- X int team = 1;
- X char *plane; /* name of plane type */
- X
- X recoverAcmArgv (switches, &argc, argv);
- X
- X
- X geomSpec = NULL;
- X u = (viewer *) malloc (sizeof(viewer));
- X
- X/*
- X * Parse command line
- X */
- X
- X for (c = &argv[1]; *c != (char *) NULL; ++c)
- X if (**c == '-') {
- X for (swp = &swt[0]; swp->value != 0; ++swp)
- X if (strcmp (swp->sw, *c) == 0) {
- X
- X switch (swp->value) {
- X
- X case SW_GEOM:
- X geomSpec = *(++c);
- X break;
- X
- X case SW_BORDER:
- X borderWidth = atoi (*(++c));
- X break;
- X
- X case SW_BACKGROUND:
- X background = *(++c);
- X break;
- X
- X case SW_HUDFONT:
- X hudfont = *(++c);
- X break;
- X
- X case SW_RADARFONT:
- X radarfont = *(++c);
- X break;
- X
- X case SW_TEAM:
- X team = atoi (*(++c));
- X break;
- X }
- X break;
- X }
- X if (swp->value == 0) {
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf (err, "%s: invalid switch %s", ACM, *c);
- X write (s, err, strlen(err));
- X exit (1);
- X }
- X }
- X
- X if (team == 1)
- X plane = "f-16c";
- X else
- X plane = "mig-23";
- X
- X if ((player = newPlane (plane)) < 0) {
- X sprintf (err, "Sorry, acm is popular -- no room for \
- Xany more players at this moment.\n");
- X write (s, err, strlen(err));
- X return -1;
- X }
- X
- X/*
- X * assign a (kludged) team location.
- X */
- X
- X if (team == 2) {
- X ptbl[player].Sg.x = -0.6 * NM + 50.0;
- X ptbl[player].Sg.y = 49.0 * NM;
- X }
- X
- X if ((u->dpy = XOpenDisplay(display)) == (Display *) NULL) {
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf(err, "%s: can't open %s\n", ACM, display);
- X write (s, err, strlen(err));
- X return -1;
- X }
- X screen = DefaultScreen (u->dpy);
- X mono = (DisplayPlanes (u->dpy, screen) == 1) ? 1 : 0;
- X
- X if ((fontName = XGetDefault(u->dpy, ACM, ARG_FONT)) == NULL) {
- X fontName = FONT;
- X }
- X if ((u->font = XLoadQueryFont(u->dpy, fontName)) == NULL) {
- X XCloseDisplay (u->dpy);
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf(err, "%s: display %s doesn't know font %s\n",
- X ACM, display, fontName);
- X write (s, err, strlen(err));
- X return -1;
- X }
- X u->fth = u->font->max_bounds.ascent + u->font->max_bounds.descent;
- X u->ftw = u->font->max_bounds.width;
- X
- X if ((fontName = XGetDefault(u->dpy, ACM, ARG_RADAR_FONT)) == NULL) {
- X fontName = DEFAULT_RADAR_FONT;
- X }
- X if ((u->rfont = XLoadQueryFont(u->dpy, fontName)) == NULL) {
- X XCloseDisplay (u->dpy);
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf(err, "%s: display %s doesn't know font %s\n",
- X ACM, display, fontName);
- X write (s, err, strlen(err));
- X return -1;
- X }
- X u->rfth = u->rfont->max_bounds.ascent + u->rfont->max_bounds.descent;
- X u->rftw = u->rfont->max_bounds.width;
- X
- X/*
- X * Select colors for the border, the window background, and the
- X * foreground. We use the default colormap to allocate the colors in.
- X */
- X
- X cmap = DefaultColormap(u->dpy, screen);
- X
- X if (background == NULL)
- X background = DEFAULT_BACKGROUND;
- X
- X if ((tempstr = XGetDefault(u->dpy, ACM, ARG_BORDER_COLOR)) == NULL)
- X tempstr = DEFAULT_BORDER;
- X if (XParseColor(u->dpy, cmap, tempstr, &color) == 0) {
- X XCloseDisplay (u->dpy);
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf (err, "Can't get border color %s\n", tempstr);
- X write (s, err, strlen(err));
- X return -1;
- X }
- X
- X if (mono)
- X bd = BlackPixel (u->dpy, screen);
- X else {
- X if (XAllocColor(u->dpy, cmap, &color) == 0) {
- X XCloseDisplay (u->dpy);
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf (err, "Cannot allocate color cells\n");
- X write (s, err, strlen(err));
- X return -1;
- X }
- X bd = color.pixel;
- X }
- X
- X/*
- X * Set the border width of the window, and the gap between the text
- X * and the edge of the window, "pad".
- X */
- X
- X pad = BORDER;
- X if ((tempstr = XGetDefault(u->dpy, ACM, ARG_BORDER)) == NULL)
- X bw = 1;
- X else
- X bw = atoi(tempstr);
- X
- X/*
- X * Deal with providing the window with an initial position & size.
- X * Fill out the XSizeHints struct to inform the window manager.
- X */
- X
- X if (geomSpec == NULL)
- X geomSpec = XGetDefault(u->dpy, ACM, ARG_GEOMETRY);
- X
- X/*
- X * If the defaults database doesn't contain a specification of the
- X * initial size & position - fit the window to the text and locate
- X * it in the center of the screen.
- X */
- X
- X if (geomSpec == NULL) {
- X xsh.flags = PPosition | PSize;
- X xsh.height = FS_WINDOW_HEIGHT;
- X xsh.width = FS_WINDOW_WIDTH;
- X xsh.x = (DisplayWidth(u->dpy, screen) - xsh.width) / 2;
- X xsh.y = (DisplayHeight(u->dpy, screen) - xsh.height) / 2;
- X }
- X else {
- X int bitmask;
- X
- X bzero((char *) &xsh, sizeof(xsh));
- X bitmask = XGeometry(u->dpy, screen, geomSpec, geomSpec,
- X bw, u->ftw, u->fth, pad, pad, &(xsh.x), &(xsh.y),
- X &(xsh.width), &(xsh.height));
- X if (bitmask & (XValue | YValue)) {
- X xsh.flags |= USPosition;
- X }
- X if (bitmask & (WidthValue | HeightValue)) {
- X xsh.flags |= USSize;
- X }
- X }
- X
- X/*
- X * Create the Window with the information in the XSizeHints, the
- X * border width, and the border & background pixels.
- X */
- X
- X u->win = XCreateSimpleWindow(u->dpy, DefaultRootWindow(u->dpy),
- X xsh.x, xsh.y, xsh.width, xsh.height,
- X bw, bd, 1);
- X
- X scale = (double) xsh.width / (double) FS_WINDOW_WIDTH;
- X width = xsh.width;
- X height = xsh.height;
- X
- X/*
- X * Create a pixmap of the engine RPM gauge and flap indicators.
- X */
- X
- X u->eng = XCreateBitmapFromData (u->dpy, u->win, eng_bits, eng_width,
- X eng_height);
- X u->flap[0] = XCreateBitmapFromData (u->dpy, u->win, flaps0_bits,
- X flaps0_width, flaps0_height);
- X u->flap[1] = XCreateBitmapFromData (u->dpy, u->win, flaps1_bits,
- X flaps1_width, flaps1_height);
- X u->flap[2] = XCreateBitmapFromData (u->dpy, u->win, flaps2_bits,
- X flaps2_width, flaps2_height);
- X u->flap[3] = XCreateBitmapFromData (u->dpy, u->win, flaps3_bits,
- X flaps3_width, flaps3_height);
- X
- X/*
- X * Set the standard properties for the window managers.
- X */
- X
- X XSetStandardProperties(u->dpy, u->win, ACM, ACM, None, argv, argc, &xsh);
- X XSetWMHints(u->dpy, u->win, &xwmh);
- X
- X xsh.width = RADAR_WINDOW_WIDTH * scale;
- X xsh.height = RADAR_WINDOW_HEIGHT * scale;
- X xsh.x = RADAR_X * scale;
- X xsh.y = RADAR_Y * scale;
- X u->rwin = XCreateWindow (u->dpy, u->win, xsh.x, xsh.y, xsh.width,
- X xsh.height, 0, CopyFromParent, CopyFromParent, CopyFromParent,
- X 0, NULL);
- X
- X/*
- X * Ensure that the window's colormap field points to the default
- X * colormap, so that the window manager knows the correct colormap to
- X * use for the window. Also, set the window's Bit
- X * Gravity to reduce Expose events.
- X */
- X
- X xswa.colormap = DefaultColormap(u->dpy, screen);
- X xswa.bit_gravity = NorthWestGravity;
- X XChangeWindowAttributes(u->dpy, u->win, (CWColormap | CWBitGravity), &xswa);
- X
- X/*
- X * Create the GC for drawing the picture.
- X */
- X
- X gcv.font = u->font->fid;
- X curGC = XCreateGC(u->dpy, u->win, GCFont, &gcv);
- X XSelectInput(u->dpy, u->win, KeyPressMask | ButtonPressMask |
- X StructureNotifyMask | ButtonReleaseMask);
- X
- X/*
- X * Fill-in the viewer structure
- X */
- X
- X cf = &ptbl[player];
- X cf->team = player;
- X cf->vl = u;
- X strncpy (cf->name, logname, sizeof (cf->name));
- X strncpy (cf->display, display, sizeof (cf->display));
- X u->next = (viewer *) NULL;
- X u->width = VIEW_WINDOW_WIDTH * scale;
- X u->height = VIEW_WINDOW_HEIGHT * scale;
- X u->xCenter = u->width / 2;
- X u->yCenter = u->height / 2;
- X
- X u->radarWidth = RADAR_WINDOW_WIDTH * scale;
- X u->radarHeight = RADAR_WINDOW_HEIGHT * scale;
- X u->gc = curGC;
- X
- X u->TEWSx = TEWS_X * scale;
- X u->TEWSy = TEWS_Y * scale;
- X u->TEWSSize = TEWS_SIZE * scale;
- X
- X u->v = VOpenViewport (u->dpy, screen, u->win,
- X 12.0*25.4/1000.0, 0.5, scale * 0.70, u->width, u->height);
- X
- X if (VBindColors (u->v, background) < 0) {
- X XCloseDisplay (u->dpy);
- X free ((char *) u);
- X ptbl[player].type = CT_FREE;
- X sprintf (err, "Error in binding colors.\n");
- X write (s, err, strlen(err));
- X return -1;
- X }
- X
- X/*
- X * Fill in the scale structures for the airspeed/altitude HUD scales.
- X */
- X
- X u->altScale.xorg = ALT_ORG_X * scale;
- X u->altScale.yorg = ALT_ORG_Y * scale;
- X u->altScale.length = ALT_LENGTH * scale;
- X u->altScale.orientation = ALT_ORIENT;
- X u->altScale.scale = ALT_SCALE / scale;
- X u->altScale.minorInterval = ALT_MIN_INTERVAL;
- X u->altScale.minorSize = ALT_MIN_SIZE * scale;
- X u->altScale.majorInterval = ALT_MAJ_INTERVAL;
- X u->altScale.majorSize = ALT_MAJ_SIZE * scale;
- X u->altScale.indexSize = ALT_INDEX_SIZE * scale;
- X u->altScale.divisor = ALT_DIVISOR;
- X u->altScale.format = ALT_FORMAT;
- X
- X u->velScale.xorg = VEL_ORG_X * scale;
- X u->velScale.yorg = VEL_ORG_Y * scale;
- X u->velScale.length = VEL_LENGTH * scale;
- X u->velScale.orientation = VEL_ORIENT;
- X u->velScale.scale = VEL_SCALE / scale;
- X u->velScale.minorInterval = VEL_MIN_INTERVAL;
- X u->velScale.minorSize = VEL_MIN_SIZE * scale;
- X u->velScale.majorInterval = VEL_MAJ_INTERVAL;
- X u->velScale.majorSize = VEL_MAJ_SIZE * scale;
- X u->velScale.indexSize = VEL_INDEX_SIZE * scale;
- X u->velScale.divisor = VEL_DIVISOR;
- X u->velScale.format = VEL_FORMAT;
- X
- X u->hdgScale.xorg = HDG_ORG_X * scale;
- X u->hdgScale.yorg = HDG_ORG_Y * scale;
- X u->hdgScale.length = HDG_LENGTH * scale;
- X u->hdgScale.orientation = HDG_ORIENT;
- X u->hdgScale.scale = HDG_SCALE / scale;
- X u->hdgScale.minorInterval = HDG_MIN_INTERVAL;
- X u->hdgScale.minorSize = HDG_MIN_SIZE * scale;
- X u->hdgScale.majorInterval = HDG_MAJ_INTERVAL;
- X u->hdgScale.majorSize = HDG_MAJ_SIZE * scale;
- X u->hdgScale.indexSize = HDG_INDEX_SIZE * scale;
- X u->hdgScale.divisor = HDG_DIVISOR;
- X u->hdgScale.format = HDG_FORMAT;
- X
- X/*
- X * Map the window to make it visible.
- X */
- X
- X XMapWindow(u->dpy, u->win);
- X XMapWindow(u->dpy, u->rwin);
- X VExposeBuffer (u->v, u->gc);
- X
- X whitePixel = whiteColor->index;
- X blackPixel = blackColor->index;
- X HUDPixel = HUDColor->index;
- X
- X return 0;
- X
- X}
- X
- Xint killPlayer (c)
- Xcraft *c; {
- X
- X viewer *v, *vn;
- X int i;
- X
- X/*
- X * Erase our radar emissions
- X */
- X
- X for (i=0; i<MAXPLAYERS; ++i)
- X ptbl[i].rval[c->index] = 0.0;
- X
- X/*
- X * Free HUD string storage
- X */
- X
- X if (c->leftHUD[0] != (char *) NULL)
- X for (i=0; i<3; ++i) {
- X free (c->leftHUD[i]);
- X free (c->rightHUD[i]);
- X }
- X
- X/*
- X * Close viewers' display
- X */
- X
- X for (v=c->vl; v != (viewer *) NULL;) {
- X XCloseDisplay (v->dpy);
- X vn = (viewer *) v->next;
- X free ((char *) v);
- X v = vn;
- X }
- X
- X if (c->flags && FL_RECORD)
- X -- recordCount;
- X
- X c->type = CT_FREE;
- X return 0;
- X}
- *-*-END-of-./fsim/newPlayer.c-*-*
- echo x - ./fsim/missile.c
- sed 's/^X//' >./fsim/missile.c <<'*-*-END-of-./fsim/missile.c-*-*'
- X/*
- X * xflight : an aerial combat simulator for X
- X *
- X * Written by Riley Rainey, riley@mips.com
- X *
- X * Permission to use, copy, modify and distribute (without charge) this
- X * software, documentation, images, etc. is granted, provided that this
- X * comment and the author's name is retained.
- X *
- X */
- X
- X#include "pm.h"
- X#include <math.h>
- X
- Xtypedef struct _entry {
- X double time;
- X double min;
- X craft *c;
- X struct _entry *next;
- X } entry;
- X
- X
- Xextern craftType *lookupCraft();
- Xextern int mdebug;
- X
- Xint fireMissile (c)
- Xcraft *c; {
- X
- X register craft *m;
- X register int i;
- X VPoint s;
- X
- X for ((i=0, m= &mtbl[0]); i<MAXPROJECTILES; (++i, ++m))
- X if (m->type == CT_FREE) {
- X m->type = CT_MISSILE;
- X break;
- X }
- X
- X if (i == MAXPROJECTILES)
- X return -1;
- X
- X m->cinfo = lookupCraft ("aim-9m");
- X m->fuel = m->cinfo->maxFuel;
- X m->curThrust = m->cinfo->maxThrust;
- X m->trihedral = c->trihedral;
- X m->Itrihedral = c->Itrihedral;
- X m->curRoll = c->curRoll;
- X m->curPitch = c->curPitch;
- X m->curHeading = c->curHeading;
- X m->Cg = c->Cg;
- X VTransform (&(c->cinfo->wStation[1]), &(c->trihedral), &s);
- X m->Sg.x = c->Sg.x + s.x;
- X m->Sg.y = c->Sg.y + s.y;
- X m->Sg.z = c->Sg.z + s.z;
- X m->armFuse = (int) (m->cinfo->armDelay / deltaT);
- X m->flags = FL_HAS_GYRO;
- X
- X/*
- X * kludge
- X */
- X
- X m->curRadarTarget = c->curRadarTarget;
- X
- X return 0;
- X}
- X
- Xint killMissile (c)
- Xcraft *c; {
- X
- X c->type = CT_FREE;
- X return 0;
- X}
- X
- Xint lookForImpacts () {
- X
- X craft *c, *m;
- X entry p[MAXPLAYERS], *list, *q, *r, *rprev;
- X VPoint v, s0;
- X double t, d;
- X int i, j;
- X
- X for (m=mtbl, i=0; i<MAXPROJECTILES; ++i, ++m) {
- X
- X if (m->type != CT_MISSILE || m->armFuse > 0)
- X continue;
- X
- X list = (entry *) NULL;
- X for (c=ptbl, j=0; j<MAXPLAYERS; ++j, ++c) {
- X
- X if (c->type == CT_FREE)
- X continue;
- X
- X/*
- X * Reduce the relative motion of this object to a the parametric system
- X * of equations:
- X * x(t) = vx * t + s0x
- X * y(t) = vy * t + s0y
- X * z(t) = vz * t + s0z
- X *
- X * We can then compute the time of perigee (closest pass) along with
- X * the associated minimum distance.
- X */
- X
- X v.x = c->Sg.x - c->prevSg.x - m->Sg.x + m->prevSg.x;
- X v.y = c->Sg.y - c->prevSg.y - m->Sg.y + m->prevSg.y;
- X v.z = c->Sg.z - c->prevSg.z - m->Sg.z + m->prevSg.z;
- X s0.x = c->prevSg.x - m->prevSg.x;
- X s0.y = c->prevSg.y - m->prevSg.y;
- X s0.z = c->prevSg.z - m->prevSg.z;
- X
- X/*
- X * Compute time of minimum distance between the two objects (note that units
- X * here are UPDATE_INTERVAL seconds).
- X */
- X
- X t = - (v.x * s0.x + v.y * s0.y + v.z * s0.z) /
- X (v.x * v.x + v.y * v.y + v.z * v.z);
- X
- X if (mdebug)
- X printf ("perigee in %g seconds with player %d\n", t*8.0, j);
- X
- X/*
- X * If the closest pass occurs during this update interval, check for a hit.
- X * We'll build a linked list of all craft that this projectile may strike
- X * during this period, arranged in ascending order by time of "perigee"
- X * (closest pass). We'll then test for strikes. If a projectile misses
- X * the first object, then it may have struck subsequent objects in the
- X * list ...
- X */
- X
- X/*
- X * One special case occurs when a target or missile's turn suddenly
- X * changes the perigee time from positive to negative. If the missile
- X * is within hitting range at t=0 and the time of perigee is negative,
- X * then zap 'em.
- X */
- X
- X if (t < 0.0) {
- X d = sqrt (s0.x *s0.x + s0.y * s0.y +
- X s0.z * s0.z);
- X if (isMissileHit (d, c)) {
- X printf ("detected a \"curve hit\"\n");
- X t = 0.0;
- X }
- X }
- X
- X if (t >= 0.0 && t <= 1.0) {
- X q = &p[i];
- X if (list == (entry *) NULL) {
- X q->next = list;
- X list = q;
- X }
- X else if (list->time > t) {
- X q->next = list;
- X list = q;
- X }
- X else {
- X for (rprev=list, r=list->next; r != (entry *) NULL;) {
- X if (r->time > t) break;
- X rprev = r;
- X r = r->next;
- X }
- X if (rprev != list)
- X rprev->next = q;
- X q->next = r;
- X }
- X q->time = t;
- X q->c = c;
- X q->min = sqrt (pow(v.x * t + s0.x, 2.0) +
- X pow (v.y * t + s0.y, 2.0) +
- X pow (v.z * t + s0.z, 2.0) );
- X if (mdebug)
- X printf ("perigee %g feet; craft %d.\n",
- X q->min, j);
- X }
- X }
- X
- X/*
- X * Now look for missile hits in the list of perigees.
- X */
- X
- X for (r=list; r != (entry *) NULL; r=r->next)
- X if (isMissileHit (r->min, r->c)) {
- X killMissile (m);
- X killPlayer (r->c);
- X break;
- X }
- X }
- X}
- X
- Xint isMissileHit (min, c)
- Xdouble min;
- Xcraft *c; {
- X
- X return (min < 50.0) ? 1 : 0;
- X}
- X
- X#define IRScanSlope 0.57735
- X
- Xint isIRVisible (c, m, t)
- Xcraft *c;
- XVMatrix *m;
- XVPoint *t; {
- X
- X VPoint relPos;
- X
- X VTransform (&(c->Sg), m, t);
- X
- X if (t->z < 0.0)
- X return 0;
- X
- X relPos.x = t->x / (t->z * IRScanSlope);
- X relPos.y = t->y / (t->z * IRScanSlope);
- X
- X return (sqrt(relPos.x*relPos.x + relPos.y*relPos.y) > 1.0) ? 0 : 1;
- X}
- X
- Xint getIRTarget (c, m, t)
- Xcraft *c;
- XVMatrix *m;
- XVPoint *t; {
- X
- X int i, n;
- X craft *p;
- X VPoint tNew, tMin;
- X double m1, min;
- X
- X if (c->curRadarTarget != -1 && isIRVisible(&ptbl[c->curRadarTarget], m, t))
- X return c->curRadarTarget;
- X
- X/*
- X * Look for a target. Designate the closest one as a new target.
- X */
- X
- X min = 1000000.0;
- X n = -1;
- X for (i=0, p=ptbl; i<MAXPLAYERS; ++i, ++p) {
- X if (p == c)
- X continue;
- X if (p->type != CT_FREE)
- X if (isIRVisible (p, m, &tNew)) {
- X m1 = mag(tNew);
- X if (m1 < min) {
- X n = i;
- X min = m1;
- X tMin = tNew;
- X }
- X }
- X }
- X
- X *t = tMin;
- X return n;
- X}
- X
- Xvoid createMissileEyeSpace (c, eyeSpace)
- Xcraft *c;
- XVMatrix *eyeSpace; {
- X
- X VPoint CntrInt, up, C1, C2;
- X VMatrix mtx, es;
- X double Hypotenuse, h1, SinA, CosA;
- X
- X/*
- X * Create an eyeSpace transformation matrix to convert from global to
- X * local coordinates.
- X */
- X
- X CntrInt.x = c->Sg.x + c->trihedral.m[0][0];
- X CntrInt.y = c->Sg.y + c->trihedral.m[1][0];
- X CntrInt.z = c->Sg.z + c->trihedral.m[2][0];
- X
- X/*
- X * If the missile has a gyroscope, then it can determine which way "down" is
- X * and, hence, compensate for gravity. Here, we'll compensate by pointing
- X * the nose of the missile up by a maximum of 12 degrees at all times.
- X */
- X
- X if (c->flags & FL_HAS_GYRO)
- X if (c->curThrust > 0.0)
- X CntrInt.z += 0.208;
- X else
- X CntrInt.z += 0.30;
- X
- X up.x = c->Sg.x - c->trihedral.m[0][2];
- X up.y = c->Sg.y - c->trihedral.m[1][2];
- X up.z = c->Sg.z - c->trihedral.m[2][2];
- X
- X VIdentMatrix (eyeSpace);
- X eyeSpace->m[0][3] = -c->Sg.x;
- X eyeSpace->m[1][3] = -c->Sg.y;
- X eyeSpace->m[2][3] = -c->Sg.z;
- X VTransform(&CntrInt, eyeSpace, &C1);
- X
- X VIdentMatrix (&mtx);
- X Hypotenuse = sqrt(C1.x * C1.x + C1.y * C1.y);
- X if (Hypotenuse > 0.0) {
- X CosA = C1.y / Hypotenuse;
- X SinA = C1.x / Hypotenuse;
- X mtx.m[0][0] = CosA;
- X mtx.m[1][0] = SinA;
- X mtx.m[0][1] = -SinA;
- X mtx.m[1][1] = CosA;
- X es = *eyeSpace;
- X VMatrixMult(&es, &mtx, eyeSpace);
- X }
- X
- X VTransform(&CntrInt, eyeSpace, &C2);
- X VIdentMatrix (&mtx);
- X Hypotenuse = sqrt(C2.y * C2.y + C2.z * C2.z);
- X if (Hypotenuse > 0.0) {
- X CosA = C2.y / Hypotenuse;
- X SinA = -C2.z / Hypotenuse;
- X mtx.m[1][1] = CosA;
- X mtx.m[2][1] = SinA;
- X mtx.m[1][2] = -SinA;
- X mtx.m[2][2] = CosA;
- X es = *eyeSpace;
- X VMatrixMult(&es, &mtx, eyeSpace);
- X }
- X
- X VTransform (&up, eyeSpace, &C2);
- X VIdentMatrix (&mtx);
- X h1 = sqrt (C2.y * C2.y + C2.z * C2.z);
- X Hypotenuse = sqrt(C2.x * C2.x + h1 * h1);
- X if (Hypotenuse > 0.0) {
- X CosA = h1 / Hypotenuse;
- X SinA = C2.x / Hypotenuse;
- X if (C2.z < 0.0) {
- X CosA = -CosA;
- X }
- X mtx.m[0][0] = CosA;
- X mtx.m[2][0] = SinA;
- X mtx.m[0][2] = -SinA;
- X mtx.m[2][2] = CosA;
- X es = *eyeSpace;
- X VMatrixMult(&es, &mtx, eyeSpace);
- X }
- X
- X VIdentMatrix (&mtx);
- X mtx.m[1][1] = 0.0;
- X mtx.m[2][1] = 1.0;
- X mtx.m[1][2] = 1.0;
- X mtx.m[2][2] = 0.0;
- X es = *eyeSpace;
- X VMatrixMult(&es, &mtx, eyeSpace);
- X
- X}
- X
- Xvoid trackTarget (c)
- Xcraft *c; {
- X
- X VMatrix eyeSpace, mtx;
- X VPoint t, t1;
- X double v, h, m, maxTurnSlope, aMax = 30.0 * a;
- X double deltaRoll, deltaPitch, deltaYaw;
- X double cosR, sinR;
- X
- X createMissileEyeSpace (c, &eyeSpace);
- X
- X/*
- X * Now let's get to target tracking; first, if we don't already have a
- X * target designated, get one.
- X */
- X
- X/* if (c->armFuse > 0) {
- X t.x = 0.0;
- X t.y = 0.0;
- X t.z = 1.0;
- X }
- X else */if ((c->curRadarTarget = getIRTarget(c, &eyeSpace, &t)) == -1) {
- X if (mdebug)
- X printf ("Missile elects to self-destruct\n");
- X killMissile (c);
- X return;
- X }
- X
- X t.x = t.x / t.z;
- X t.y = t.y / t.z;
- X
- X h = sqrt (t.x*t.x + t.y*t.y);
- X v = mag (c->Cg);
- X
- X/*
- X * We'll constrain missile turns to a 20 degree/second unless it's velocity
- X * would make that greater than 30g's.
- X */
- X
- X if ((m=(v*v - aMax*aMax/4.0)) > 0.0)
- X maxTurnSlope = aMax / (2.0 * sqrt (m)) * deltaT;
- X
- X else
- X maxTurnSlope = 0.3639 * deltaT;
- X
- X if (mdebug)
- X printf ("slope = %g; maxTurnSlope = %g\n", h, maxTurnSlope);
- X
- X if (h > maxTurnSlope) {
- X t.x = t.x * maxTurnSlope / h;
- X t.y = t.y * maxTurnSlope / h;
- X }
- X
- X cosR = cos (c->curRoll);
- X sinR = sin (c->curRoll);
- X
- X deltaRoll = 0.0;
- X deltaPitch = atan (t.y);
- X deltaYaw = atan (t.x);
- X
- X/*
- X * Re-orient the velocity vector towards our new direction.
- X */
- X
- X VIdentMatrix (&mtx);
- X if (deltaPitch != 0.0)
- X VRotate (&mtx, YRotation, - deltaPitch);
- X if (deltaYaw != 0.0)
- X VRotate (&mtx, ZRotation, deltaYaw);
- X VTransform (&(c->Cg), &(c->Itrihedral), &t);
- X VTransform (&t, &mtx, &t1);
- X VTransform (&t1, &(c->trihedral), &(c->Cg));
- X
- X if (mdebug)
- X printf ("Missile changes: pitch: %g, yaw: %g.\n",
- X RADtoDEG(deltaPitch), RADtoDEG(deltaYaw));
- X
- X c->curRoll += deltaRoll;
- X c->curHeading += sinR * deltaPitch + cosR * deltaYaw;
- X c->curPitch += cosR * deltaPitch - sinR * deltaYaw;
- X
- X}
- *-*-END-of-./fsim/missile.c-*-*
- echo x - ./fsim/m61a1.c
- sed 's/^X//' >./fsim/m61a1.c <<'*-*-END-of-./fsim/m61a1.c-*-*'
- X/*
- X * xflight : an aerial combat simulator for X
- X *
- X * Written by Riley Rainey, riley@mips.com
- X *
- X * Permission to use, copy, modify and distribute (without charge) this
- X * software, documentation, images, etc. is granted, provided that this
- X * comment and the author's name is retained.
- X *
- X */
- X
- X#include "pm.h"
- X#include <stdio.h>
- X#include <string.h>
- X#include <math.h>
- X
- X#define BORE_CROSS_SIZE 7
- X#define MUZZLE_VELOCITY (3.2808 * 1036.0)
- X#define TRACER_MOD 10
- X#define OFFSET_ANGLE (DEGtoRAD(3.0)) /* the gun points up at this angle */
- X#define RATE_OF_FIRE (3000.0 / 60.0) /* rounds per second */
- X#define FUZZ (DEGtoRAD(1.0)) /* distribution due to vibration */
- X
- Xint select_m61a1();
- Xint display_m61a1();
- Xint update_m61a1();
- Xint press_m61a1();
- Xint release_m61a1();
- Xextern craftType * lookupCraft();
- X
- XweaponDesc m61a1Desc = {
- X WK_M61A1,
- X select_m61a1, /* select */
- X update_m61a1, /* update */
- X display_m61a1, /* display procedure */
- X press_m61a1, /* fire */
- X release_m61a1, /* fire button release */
- X };
- X
- X/*
- X * m61a1 selection function
- X *
- X * A selection function normally determines whether there are any weapons
- X * of this type on-board. If so, and the weapon system is functional
- X * (in other words, undamaged) then return 1; otherwise return 0.
- X */
- X
- Xint select_m61a1 (c)
- Xcraft *c; {
- X
- X if (c->station[0].type == WK_M61A1 && c->station[0].info > 0)
- X return 1;
- X else
- X return 0;
- X
- X}
- X
- X/*
- X * m61a1 display function
- X *
- X * Update the HUD display strings associated with this weapon system.
- X */
- X
- Xint display_m61a1 (c, w, u)
- Xcraft *c;
- XcraftType *w;
- Xviewer *u; {
- X
- X char s[16];
- X register int tx, ty, m;
- X VPoint tmp;
- X XSegment seg[2];
- X
- X strcpy (c->leftHUD[0], "LCOS");
- X sprintf (s, "%.3d M-61A1", c->station[0].info);
- X strcpy (c->leftHUD[1], s);
- X if (c->station[0].info3)
- X strcpy (c->leftHUD[2], "FIRING");
- X else
- X strcpy (c->leftHUD[2], "");
- X
- X/*
- X * Draw the boresight cross
- X */
- X
- X m = (double) BORE_CROSS_SIZE * (double) u->width /
- X (double) VIEW_WINDOW_WIDTH + 0.5;
- X
- X tx = u->xCenter;
- X ty = u->yCenter - 3 * 9; /* kludged, for now */
- X seg[0].x1 = tx - m;
- X seg[0].x2 = tx + m;
- X seg[0].y1 = seg[0].y2 = ty;
- X seg[1].x1 = seg[1].x2 = tx;
- X seg[1].y1 = ty - m;
- X seg[1].y2 = ty + m;
- X XDrawSegments (u->dpy, u->win, u->gc, seg, 2);
- X
- X/*
- X * If we have a radar target designated, then draw a reticle.
- X */
- X/*
- X if (c->curRadarTarget >= 0) {
- X VTransform (&(ptbl[c->curRadarTarget].Sg),
- X &u->v->eyeSpace, &tmp);
- X tx = u->v->Middl.x + tmp.x * u->v->Scale.x / tmp.z + 0.5;
- X ty = u->v->Middl.y - tmp.y * u->v->Scale.y / tmp.z + 0.5;
- X }
- X*/
- X}
- X
- Xint press_m61a1 (c)
- Xcraft *c; {
- X c->station[0].info3 |= 1;
- X return 0;
- X}
- X
- Xint release_m61a1 (c)
- Xcraft *c; {
- X c->station[0].info3 &= ~1;
- X return 0;
- X}
- X
- Xextern long random ();
- X
- Xint update_m61a1 (c)
- Xcraft *c; {
- X
- X craft *m;
- X int i;
- X VPoint tmp, mvel;
- X int rounds;
- X double fuzz, fuzzAngle, phiY, phiZ, tm, mv = MUZZLE_VELOCITY;
- X
- X if (c->station[0].info3 == 0)
- X return 0;
- X
- X/*
- X * Got any ammunition ?
- X */
- X
- X if (c->station[0].info <= 0)
- X return -1;
- X
- X/*
- X * Allocate a projectile record
- X */
- X
- X for ((i=0, m= &mtbl[0]); i<MAXPROJECTILES; (++i, ++m))
- X if (m->type == CT_FREE) {
- X m->type = CT_CANNON;
- X break;
- X }
- X
- X if (i == MAXPROJECTILES)
- X return -1;
- X
- X/*
- X * Determine how far we're fuzzed off the ideal boresight.
- X */
- X
- X fuzz = ((double)(random() & 32767) +
- X (double)(random() & 32767)) / 32768.0 - 1.0;
- X fuzz = fuzz * FUZZ;
- X fuzzAngle = 2.0 * pi * (double)(random() & 511) / 512.0;
- X
- X/*
- X * Determine the initial velocity of the projectile stream.
- X */
- X
- X phiZ = fuzz * sin (fuzzAngle);
- X phiY = fuzz * cos (fuzzAngle);
- X tm = mv * cos (OFFSET_ANGLE + phiZ);
- X
- X tmp.x = tm * cos (phiY);
- X tmp.y = tm * sin (phiY);
- X tmp.z = mv * sin (-OFFSET_ANGLE + phiZ);
- X VTransform (&tmp, &(c->trihedral), &mvel);
- X
- X m->createTime = curTime;
- X m->Cg = c->Cg;
- X m->curRoll = c->curRoll;
- X m->curPitch = c->curPitch;
- X m->curHeading = c->curHeading;
- X m->Cg.x += mvel.x;
- X m->Cg.y += mvel.y;
- X m->Cg.z += mvel.z;
- X
- X/*
- X * Determine the initial position.
- X */
- X
- X VTransform (&(c->cinfo->wStation[0]), &(c->trihedral), &tmp);
- X m->Sg.x = c->Sg.x + tmp.x;
- X m->Sg.y = c->Sg.y + tmp.y;
- X m->Sg.z = c->Sg.z + tmp.z;
- X
- X/*
- X * Subtract the number of rounds fired.
- X */
- X
- X m->rounds = RATE_OF_FIRE * deltaT;
- X m->rounds = (m->rounds > c->station[0].info) ? c->station[0].info : m->rounds;
- X m->tracerMod = TRACER_MOD;
- X m->tracerVal = c->station[0].info2 % m->tracerMod;
- X c->station[0].info -= m->rounds;
- X c->station[0].info2 += m->rounds;
- X
- X m->cinfo = lookupCraft ("m61a1 cannon");
- X
- X return 0;
- X
- X}
- X
- Xextern craftType * newCraft ();
- Xextern char * strdup();
- X
- Xint placeCannon(c, m, poly, cnt)
- Xcraft *c;
- XVMatrix *m;
- XVPolygon **poly;
- Xint *cnt; {
- X
- X double t, intervalT;
- X VPoint v, s;
- X int i, j, k, n;
- X VPoint *q, tmp;
- X VPolygon **p;
- X
- X/*
- X * Reduce the shell path to a set of parametric equations.
- X */
- X
- X v.x = c->Sg.x - c->prevSg.x;
- X v.y = c->Sg.y - c->prevSg.y;
- X v.z = c->Sg.z - c->prevSg.z;
- X
- X/*
- X * Now add each tracer shell to the view.
- X */
- X
- X intervalT = 1.0 / c->rounds;
- X for (t=intervalT*c->tracerVal; t <= 1.0; t += intervalT * TRACER_MOD) {
- X s.x = -v.x * t;
- X s.y = -v.y * t;
- X s.z = -v.z * t;
- X if (c->Sg.z + s.z > 0.0) /* underground? don't plot it */
- X continue;
- X n = c->cinfo->object->numPolys;
- X p = c->cinfo->object->polygon;
- X j = *cnt;
- X for (i=0; i<n; ++i) {
- X poly[j] = VCopyPolygon(p[i]);
- X for ((k=0, q=poly[j]->vertex); k<poly[j]->numVtces; (++k, ++q)) {
- X VTransform(q, m, &tmp);
- X tmp.x += s.x;
- X tmp.y += s.y;
- X tmp.z += s.z;
- X *q = tmp;
- X }
- X ++j;
- X }
- X *cnt = j;
- X }
- X
- X}
- X
- Xvoid initm61a1()
- X{
- X
- X craftType *c;
- X FILE *f;
- X
- X wtbl[1] = m61a1Desc;
- X
- X c = newCraft();
- X c->name = strdup("m61a1 cannon");
- X
- X c->placeProc = placeCannon;
- X
- X f = fopen ("bullet", "r");
- X c->object = VReadObject(f);
- X fclose (f);
- X
- X}
- X
- Xint cannonCalculations (c)
- Xcraft *c; {
- X
- X
- X/*
- X * Kill projectile streams after 10.0 seconds of flight or when
- X * they strike the ground.
- X */
- X
- X if (curTime - c->createTime > 10.0)
- X return 1;
- X
- X if (c->Sg.z > 0.0)
- X return 1;
- X
- X c->prevSg = c->Sg;
- X
- X c->Sg.x += c->Cg.x * deltaT;
- X c->Sg.y += c->Cg.y * deltaT;
- X c->Sg.z += c->Cg.z * deltaT + a * halfDeltaTSquared;
- X
- X c->Cg.z += a * deltaT;
- X return 0;
- X
- X}
- *-*-END-of-./fsim/m61a1.c-*-*
- echo x - ./fsim/README
- sed 's/^X//' >./fsim/README <<'*-*-END-of-./fsim/README-*-*'
- Xacm Flight Simulator version 1.0
- X
- XThis software is divided into two major parts: the 3-D graphics routines
- Xand the flight simulator itself. The 3-D stuff is contained in the V
- Xdirectory. V/lib holds the library itself along with imake and make files.
- XV/test contains a program that can be used to test your port of the
- XV library.
- X
- XFsim contains the remainder of the flight simulator. A makefile for
- XMips RISC/os is provided. The code has a Berkeley tilt to it in many
- Xplaces, so people with hybrid OS's will probably want to lean that
- Xdirection when selecting compiling and linking options.
- X
- XThe acm server, acms, must currently be started manually. It's intended
- Xthat it will eventually be managed automatically by inetd, but that's
- Xnot in the code yet. I have access to a network that includes a 16+ SPECMark
- Xserver and 12 to 18 SPECMark workstations (i.e. a MIPS 3260 along with
- XMIPS 2030 and Magnum workstations) (translate SPECMarks into millions of
- Xinstructions per second by whatever formula you like ..). I generally
- Xrlogin to the 3260 and start the acms process on it and leave that xterm
- Xwindow hanging around; then, from another xterm window, I'll fire off
- Xthe acm command that starts my flying session. Other players enter the
- Xgame by simply firing off an "acm servername" command.
- X
- XI'm not saying that acm is a particularly accurate flight simulator. I'm
- Xnot an aero engineer, but I did spend a fair amount of time studying
- Xseveral college-level texts on the subject while I was designing this
- Xsoftware. This probably doesn't resemble real-time flight simulators
- Xtoo much but, again, that's not my line of work. Comments and
- Xsuggestions to improve this software are welcome.
- X
- XSeveral "features" in this revision of the software:
- X
- X * landing gear is ignored. Raise it, lower it; it's
- X not handled by the software.
- X
- X * flaps can be lowered at rediculously high speeds.
- X
- X * cannon fire will not hit other aircraft. Missiles
- X sure will, though.
- X
- X * you can fly through mountains.
- X
- X * engines do not flame-out. Fly really high (and fast enough)
- X and you can just about get into orbit. Non-afterburning
- X engine performance does degrade as altitude increases, but
- X afterburner performance gives the extra kick needed to fly
- X much higher than you should be able to.
- X
- X * A hit kills you instantly. acm does not currently have a
- X notion of limited aircraft damage. It may in the future.
- X
- X
- XRiley Rainey
- XOctober 1, 1990
- *-*-END-of-./fsim/README-*-*
- echo x - ./fsim/update.c
- sed 's/^X//' >./fsim/update.c <<'*-*-END-of-./fsim/update.c-*-*'
- X/*
- X * xflight : an aerial combat simulator for X
- X *
- X * Written by Riley Rainey, riley@mips.com
- X *
- X * Permission to use, copy, modify and distribute (without charge) this
- X * software, documentation, images, etc. is granted, provided that this
- X * comment and the author's name is retained.
- X *
- X */
- X
- X#include "pm.h"
- X#include <X11/Xutil.h>
- X
- Xextern int flightCalculations();
- Xextern int missileCalculations();
- Xextern void doEvents(), doViews(), flapControl();
- X
- Xint cur = 0;
- X
- Xint redraw () {
- X
- X int i, j;
- X craft *p;
- X
- X for ((i=0, p=ptbl); i<MAXPLAYERS; (++i, ++p)) {
- X if (p->type == CT_PLANE) {
- X doEvents (p);
- X if (flightCalculations (p) == 1)
- X killPlayer (p);
- X doWeaponUpdate (p);
- X flapControl (p);
- X }
- X else if (p->type == CT_DRONE)
- X if (droneCalculations (p) == 1)
- X killPlayer (p);
- X }
- X
- X for ((i=0, p=mtbl); i<MAXPROJECTILES; (++i, ++p)) {
- X if (p->type == CT_MISSILE) {
- X if (missileCalculations (p) == 1)
- X killMissile (p);
- X }
- X else if (p->type == CT_CANNON)
- X if (cannonCalculations (p) == 1)
- X killMissile (p);
- X }
- X
- X lookForImpacts ();
- X
- X if (cur++ % REDRAW_EVERY == 0)
- X doViews ();
- X
- X curTime += deltaT;
- X
- X return 0;
- X
- X}
- *-*-END-of-./fsim/update.c-*-*
- echo x - ./fsim/rwy.old
- sed 's/^X//' >./fsim/rwy.old <<'*-*-END-of-./fsim/rwy.old-*-*'
- XRunway
- X280 69
- X1 0.000000 -75.000000 0.000000
- X2 12000.000000 -75.000000 0.000000
- X3 12000.000000 75.000000 0.000000
- X4 0.000000 75.000000 0.000000
- X5 0.000000 -75.000000 0.000000
- X6 12000.000000 -75.000000 0.000000
- X7 12000.000000 -70.000000 0.000000
- X8 0.000000 -70.000000 0.000000
- X9 0.000000 75.000000 0.000000
- X10 12000.000000 75.000000 0.000000
- X11 12000.000000 70.000000 0.000000
- X12 0.000000 70.000000 0.000000
- X13 1000.000000 -66.000000 0.000000
- X14 1125.000000 -66.000000 0.000000
- X15 1125.000000 -36.000000 0.000000
- X16 1000.000000 -36.000000 0.000000
- X17 1000.000000 66.000000 0.000000
- X18 1125.000000 66.000000 0.000000
- X19 1125.000000 36.000000 0.000000
- X20 1000.000000 36.000000 0.000000
- X21 11000.000000 -66.000000 0.000000
- X22 10875.000000 -66.000000 0.000000
- X23 10875.000000 -36.000000 0.000000
- X24 11000.000000 -36.000000 0.000000
- X25 11000.000000 66.000000 0.000000
- X26 10875.000000 66.000000 0.000000
- X27 10875.000000 36.000000 0.000000
- X28 11000.000000 36.000000 0.000000
- X29 4.000000 -66.000000 0.000000
- X30 129.000000 -66.000000 0.000000
- X31 129.000000 -54.888889 0.000000
- X32 4.000000 -54.888889 0.000000
- X33 4.000000 -50.888889 0.000000
- X34 129.000000 -50.888889 0.000000
- X35 129.000000 -39.777779 0.000000
- X36 4.000000 -39.777779 0.000000
- X37 4.000000 -35.777779 0.000000
- X38 129.000000 -35.777779 0.000000
- X39 129.000000 -24.666666 0.000000
- X40 4.000000 -24.666666 0.000000
- X41 4.000000 -20.666666 0.000000
- X42 129.000000 -20.666666 0.000000
- X43 129.000000 -9.555555 0.000000
- X44 4.000000 -9.555555 0.000000
- X45 4.000000 9.555555 0.000000
- X46 129.000000 9.555555 0.000000
- X47 129.000000 20.666666 0.000000
- X48 4.000000 20.666666 0.000000
- X49 4.000000 24.666666 0.000000
- X50 129.000000 24.666666 0.000000
- X51 129.000000 35.777779 0.000000
- X52 4.000000 35.777779 0.000000
- X53 4.000000 39.777779 0.000000
- X54 129.000000 39.777779 0.000000
- X55 129.000000 50.888889 0.000000
- X56 4.000000 50.888889 0.000000
- X57 4.000000 54.888889 0.000000
- X58 129.000000 54.888889 0.000000
- X59 129.000000 66.000000 0.000000
- X60 4.000000 66.000000 0.000000
- X61 11996.000000 -66.000000 0.000000
- X62 11871.000000 -66.000000 0.000000
- X63 11871.000000 -54.888889 0.000000
- X64 11996.000000 -54.888889 0.000000
- X65 11996.000000 -50.888889 0.000000
- X66 11871.000000 -50.888889 0.000000
- X67 11871.000000 -39.777779 0.000000
- X68 11996.000000 -39.777779 0.000000
- X69 11996.000000 -35.777779 0.000000
- X70 11871.000000 -35.777779 0.000000
- X71 11871.000000 -24.666666 0.000000
- X72 11996.000000 -24.666666 0.000000
- X73 11996.000000 -20.666666 0.000000
- X74 11871.000000 -20.666666 0.000000
- X75 11871.000000 -9.555555 0.000000
- X76 11996.000000 -9.555555 0.000000
- X77 11996.000000 9.555555 0.000000
- X78 11871.000000 9.555555 0.000000
- X79 11871.000000 20.666666 0.000000
- X80 11996.000000 20.666666 0.000000
- X81 11996.000000 24.666666 0.000000
- X82 11871.000000 24.666666 0.000000
- X83 11871.000000 35.777779 0.000000
- X84 11996.000000 35.777779 0.000000
- X85 11996.000000 39.777779 0.000000
- X86 11871.000000 39.777779 0.000000
- X87 11871.000000 50.888889 0.000000
- X88 11996.000000 50.888889 0.000000
- X89 11996.000000 54.888889 0.000000
- X90 11871.000000 54.888889 0.000000
- X91 11871.000000 66.000000 0.000000
- X92 11996.000000 66.000000 0.000000
- X93 258.000000 -2.500000 0.000000
- X94 383.000000 -2.500000 0.000000
- X95 383.000000 2.500000 0.000000
- X96 258.000000 2.500000 0.000000
- X97 508.000000 -2.500000 0.000000
- X98 633.000000 -2.500000 0.000000
- X99 633.000000 2.500000 0.000000
- X100 508.000000 2.500000 0.000000
- X101 758.000000 -2.500000 0.000000
- X102 883.000000 -2.500000 0.000000
- X103 883.000000 2.500000 0.000000
- X104 758.000000 2.500000 0.000000
- X105 1008.000000 -2.500000 0.000000
- X106 1133.000000 -2.500000 0.000000
- X107 1133.000000 2.500000 0.000000
- X108 1008.000000 2.500000 0.000000
- X109 1258.000000 -2.500000 0.000000
- X110 1383.000000 -2.500000 0.000000
- X111 1383.000000 2.500000 0.000000
- X112 1258.000000 2.500000 0.000000
- X113 1508.000000 -2.500000 0.000000
- X114 1633.000000 -2.500000 0.000000
- X115 1633.000000 2.500000 0.000000
- X116 1508.000000 2.500000 0.000000
- X117 1758.000000 -2.500000 0.000000
- X118 1883.000000 -2.500000 0.000000
- X119 1883.000000 2.500000 0.000000
- X120 1758.000000 2.500000 0.000000
- X121 2008.000000 -2.500000 0.000000
- X122 2133.000000 -2.500000 0.000000
- X123 2133.000000 2.500000 0.000000
- X124 2008.000000 2.500000 0.000000
- X125 2258.000000 -2.500000 0.000000
- X126 2383.000000 -2.500000 0.000000
- X127 2383.000000 2.500000 0.000000
- X128 2258.000000 2.500000 0.000000
- X129 2508.000000 -2.500000 0.000000
- X130 2633.000000 -2.500000 0.000000
- X131 2633.000000 2.500000 0.000000
- X132 2508.000000 2.500000 0.000000
- X133 2758.000000 -2.500000 0.000000
- X134 2883.000000 -2.500000 0.000000
- X135 2883.000000 2.500000 0.000000
- X136 2758.000000 2.500000 0.000000
- X137 3008.000000 -2.500000 0.000000
- X138 3133.000000 -2.500000 0.000000
- X139 3133.000000 2.500000 0.000000
- X140 3008.000000 2.500000 0.000000
- X141 3258.000000 -2.500000 0.000000
- X142 3383.000000 -2.500000 0.000000
- X143 3383.000000 2.500000 0.000000
- X144 3258.000000 2.500000 0.000000
- X145 3508.000000 -2.500000 0.000000
- X146 3633.000000 -2.500000 0.000000
- X147 3633.000000 2.500000 0.000000
- X148 3508.000000 2.500000 0.000000
- X149 3758.000000 -2.500000 0.000000
- X150 3883.000000 -2.500000 0.000000
- X151 3883.000000 2.500000 0.000000
- X152 3758.000000 2.500000 0.000000
- X153 4008.000000 -2.500000 0.000000
- X154 4133.000000 -2.500000 0.000000
- X155 4133.000000 2.500000 0.000000
- X156 4008.000000 2.500000 0.000000
- X157 4258.000000 -2.500000 0.000000
- X158 4383.000000 -2.500000 0.000000
- X159 4383.000000 2.500000 0.000000
- X160 4258.000000 2.500000 0.000000
- X161 4508.000000 -2.500000 0.000000
- X162 4633.000000 -2.500000 0.000000
- X163 4633.000000 2.500000 0.000000
- X164 4508.000000 2.500000 0.000000
- X165 4758.000000 -2.500000 0.000000
- X166 4883.000000 -2.500000 0.000000
- X167 4883.000000 2.500000 0.000000
- X168 4758.000000 2.500000 0.000000
- X169 5008.000000 -2.500000 0.000000
- X170 5133.000000 -2.500000 0.000000
- X171 5133.000000 2.500000 0.000000
- X172 5008.000000 2.500000 0.000000
- X173 5258.000000 -2.500000 0.000000
- X174 5383.000000 -2.500000 0.000000
- X175 5383.000000 2.500000 0.000000
- X176 5258.000000 2.500000 0.000000
- X177 5508.000000 -2.500000 0.000000
- X178 5633.000000 -2.500000 0.000000
- X179 5633.000000 2.500000 0.000000
- X180 5508.000000 2.500000 0.000000
- X181 5758.000000 -2.500000 0.000000
- X182 5883.000000 -2.500000 0.000000
- X183 5883.000000 2.500000 0.000000
- X184 5758.000000 2.500000 0.000000
- X185 6008.000000 -2.500000 0.000000
- X186 6133.000000 -2.500000 0.000000
- X187 6133.000000 2.500000 0.000000
- X188 6008.000000 2.500000 0.000000
- X189 6258.000000 -2.500000 0.000000
- X190 6383.000000 -2.500000 0.000000
- X191 6383.000000 2.500000 0.000000
- X192 6258.000000 2.500000 0.000000
- X193 6508.000000 -2.500000 0.000000
- X194 6633.000000 -2.500000 0.000000
- X195 6633.000000 2.500000 0.000000
- X196 6508.000000 2.500000 0.000000
- X197 6758.000000 -2.500000 0.000000
- X198 6883.000000 -2.500000 0.000000
- X199 6883.000000 2.500000 0.000000
- X200 6758.000000 2.500000 0.000000
- X201 7008.000000 -2.500000 0.000000
- X202 7133.000000 -2.500000 0.000000
- X203 7133.000000 2.500000 0.000000
- X204 7008.000000 2.500000 0.000000
- X205 7258.000000 -2.500000 0.000000
- X206 7383.000000 -2.500000 0.000000
- X207 7383.000000 2.500000 0.000000
- X208 7258.000000 2.500000 0.000000
- X209 7508.000000 -2.500000 0.000000
- X210 7633.000000 -2.500000 0.000000
- X211 7633.000000 2.500000 0.000000
- X212 7508.000000 2.500000 0.000000
- X213 7758.000000 -2.500000 0.000000
- X214 7883.000000 -2.500000 0.000000
- X215 7883.000000 2.500000 0.000000
- X216 7758.000000 2.500000 0.000000
- X217 8008.000000 -2.500000 0.000000
- X218 8133.000000 -2.500000 0.000000
- X219 8133.000000 2.500000 0.000000
- X220 8008.000000 2.500000 0.000000
- X221 8258.000000 -2.500000 0.000000
- X222 8383.000000 -2.500000 0.000000
- X223 8383.000000 2.500000 0.000000
- X224 8258.000000 2.500000 0.000000
- X225 8508.000000 -2.500000 0.000000
- X226 8633.000000 -2.500000 0.000000
- X227 8633.000000 2.500000 0.000000
- X228 8508.000000 2.500000 0.000000
- X229 8758.000000 -2.500000 0.000000
- X230 8883.000000 -2.500000 0.000000
- X231 8883.000000 2.500000 0.000000
- X232 8758.000000 2.500000 0.000000
- X233 9008.000000 -2.500000 0.000000
- X234 9133.000000 -2.500000 0.000000
- X235 9133.000000 2.500000 0.000000
- X236 9008.000000 2.500000 0.000000
- X237 9258.000000 -2.500000 0.000000
- X238 9383.000000 -2.500000 0.000000
- X239 9383.000000 2.500000 0.000000
- X240 9258.000000 2.500000 0.000000
- X241 9508.000000 -2.500000 0.000000
- X242 9633.000000 -2.500000 0.000000
- X243 9633.000000 2.500000 0.000000
- X244 9508.000000 2.500000 0.000000
- X245 9758.000000 -2.500000 0.000000
- X246 9883.000000 -2.500000 0.000000
- X247 9883.000000 2.500000 0.000000
- X248 9758.000000 2.500000 0.000000
- X249 10008.000000 -2.500000 0.000000
- X250 10133.000000 -2.500000 0.000000
- X251 10133.000000 2.500000 0.000000
- X252 10008.000000 2.500000 0.000000
- X253 10258.000000 -2.500000 0.000000
- X254 10383.000000 -2.500000 0.000000
- X255 10383.000000 2.500000 0.000000
- X256 10258.000000 2.500000 0.000000
- X257 10508.000000 -2.500000 0.000000
- X258 10633.000000 -2.500000 0.000000
- X259 10633.000000 2.500000 0.000000
- X260 10508.000000 2.500000 0.000000
- X261 10758.000000 -2.500000 0.000000
- X262 10883.000000 -2.500000 0.000000
- X263 10883.000000 2.500000 0.000000
- X264 10758.000000 2.500000 0.000000
- X265 11008.000000 -2.500000 0.000000
- X266 11133.000000 -2.500000 0.000000
- X267 11133.000000 2.500000 0.000000
- X268 11008.000000 2.500000 0.000000
- X269 11258.000000 -2.500000 0.000000
- X270 11383.000000 -2.500000 0.000000
- X271 11383.000000 2.500000 0.000000
- X272 11258.000000 2.500000 0.000000
- X273 11508.000000 -2.500000 0.000000
- X274 11633.000000 -2.500000 0.000000
- X275 11633.000000 2.500000 0.000000
- X276 11508.000000 2.500000 0.000000
- X277 11758.000000 -2.500000 0.000000
- X278 11883.000000 -2.500000 0.000000
- X279 11883.000000 2.500000 0.000000
- X280 11758.000000 2.500000 0.000000
- X#b7b19f 4 1 2 3 4
- Xwhite 4 5 6 7 8
- Xwhite 4 9 10 11 12
- Xwhite 4 13 14 15 16
- Xwhite 4 17 18 19 20
- Xwhite 4 21 22 23 24
- Xwhite 4 25 26 27 28
- Xwhite 4 29 30 31 32
- Xwhite 4 33 34 35 36
- Xwhite 4 37 38 39 40
- Xwhite 4 41 42 43 44
- Xwhite 4 45 46 47 48
- Xwhite 4 49 50 51 52
- Xwhite 4 53 54 55 56
- Xwhite 4 57 58 59 60
- Xwhite 4 61 62 63 64
- Xwhite 4 65 66 67 68
- Xwhite 4 69 70 71 72
- Xwhite 4 73 74 75 76
- Xwhite 4 77 78 79 80
- Xwhite 4 81 82 83 84
- Xwhite 4 85 86 87 88
- Xwhite 4 89 90 91 92
- Xwhite 4 93 94 95 96
- Xwhite 4 97 98 99 100
- Xwhite 4 101 102 103 104
- Xwhite 4 105 106 107 108
- Xwhite 4 109 110 111 112
- Xwhite 4 113 114 115 116
- Xwhite 4 117 118 119 120
- Xwhite 4 121 122 123 124
- Xwhite 4 125 126 127 128
- Xwhite 4 129 130 131 132
- Xwhite 4 133 134 135 136
- Xwhite 4 137 138 139 140
- Xwhite 4 141 142 143 144
- Xwhite 4 145 146 147 148
- Xwhite 4 149 150 151 152
- Xwhite 4 153 154 155 156
- Xwhite 4 157 158 159 160
- Xwhite 4 161 162 163 164
- Xwhite 4 165 166 167 168
- Xwhite 4 169 170 171 172
- Xwhite 4 173 174 175 176
- Xwhite 4 177 178 179 180
- Xwhite 4 181 182 183 184
- Xwhite 4 185 186 187 188
- Xwhite 4 189 190 191 192
- Xwhite 4 193 194 195 196
- Xwhite 4 197 198 199 200
- Xwhite 4 201 202 203 204
- Xwhite 4 205 206 207 208
- Xwhite 4 209 210 211 212
- Xwhite 4 213 214 215 216
- Xwhite 4 217 218 219 220
- Xwhite 4 221 222 223 224
- Xwhite 4 225 226 227 228
- Xwhite 4 229 230 231 232
- Xwhite 4 233 234 235 236
- Xwhite 4 237 238 239 240
- Xwhite 4 241 242 243 244
- Xwhite 4 245 246 247 248
- Xwhite 4 249 250 251 252
- Xwhite 4 253 254 255 256
- Xwhite 4 257 258 259 260
- Xwhite 4 261 262 263 264
- Xwhite 4 265 266 267 268
- Xwhite 4 269 270 271 272
- Xwhite 4 273 274 275 276
- Xwhite 4 277 278 279 280
- *-*-END-of-./fsim/rwy.old-*-*
- --
- Riley Rainey Internet: riley@mips.com
- MIPS Computer Systems Phone: +1 214 770-7979
- Dallas, Texas
-
- dan
- ----------------------------------------------------
- O'Reilly && Associates argv@sun.com / argv@ora.com
- Opinions expressed reflect those of the author only.
-